package org.example.supplychain.controller;

import jakarta.servlet.http.HttpSession;
import org.example.supplychain.domain.EntryExitRecords;
import org.example.supplychain.domain.Inventory;
import org.example.supplychain.domain.Supplier;
import org.example.supplychain.domain.TotalMaterial;
import org.example.supplychain.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

/**
 * 库存管理的Controller
 */
@Controller
@RequestMapping("/inventory")
public class InventoryController {
    @Autowired
    InventoryService inventoryService;
    @Autowired
    EntryExitRecordsService entryExitRecordsService;
    @Autowired
    TotalMaterialService totalMaterialService;
    @Autowired
    OrderService orderService;
    @Autowired
    SupplierService supplierService;

    @GetMapping("")
    public String home() {
        return "inventoryKeeper";
    }

    @GetMapping("/record")
    public String record(HttpSession session) {

        List<Supplier> suppliers = supplierService.getAllSuppliers();
        List<Inventory> inventories = inventoryService.getAllInventories();
        session.setAttribute("suppliers", suppliers);
        session.setAttribute("inventories", inventories);
        return "record";
    }

    @GetMapping("/management")
    public String inventoryManagement() {
        return "inventoryManagement";
    }

    @GetMapping("/warning")
    public String warning() {
        return "warning";
    }

    @GetMapping("/supplier")
    public String supplier() {
        return "supplierManagement";
    }


    @PostMapping("/insert")
    public String insert(@RequestParam(value = "inventoryName") String inventoryName, @RequestParam(value = "inventoryPlace") String inventoryPlace,
                         @RequestParam(value = "inventoryManager") String inventoryManager, Model model) {
        Inventory inventory = new Inventory();
        inventory.setInventoryName(inventoryName);
        inventory.setInventoryPlace(inventoryPlace);
        inventory.setInventoryManager(inventoryManager);
        try {
            inventoryService.addInventory(inventory);
            model.addAttribute("successInsertInventory", "Successfully Insert Inventory!!!");
        } catch (Exception e) {
            model.addAttribute("failInsertInventory", "Fail to Insert Inventory!!!");
        }
        return "inventoryManagement";
    }


    @PostMapping("/all")
    public String getInventoryByIndex(@RequestParam("warehouseName") String inventoryName, @RequestParam("warehouseAddress") String inventoryPlace, @RequestParam("warehouseManager") String inventoryManager, HttpSession session, Model model) {
        List<Inventory> inventoryList = inventoryService.getAllInventories();
        if (inventoryList == null) {
            model.addAttribute("noInventory", "No inventory!!!");
            return "inventoryManagement";
        }
        Stream<Inventory> inventoryStream = inventoryList.stream();
        if (!inventoryName.isEmpty()) {
            inventoryStream = inventoryStream.filter(e -> e.getInventoryName().contains(inventoryName));
        }
        if (!inventoryPlace.isEmpty()) {
            inventoryStream = inventoryStream.filter(e -> e.getInventoryPlace().contains(inventoryPlace));
        }
        if (!inventoryManager.isEmpty()) {
            inventoryStream = inventoryStream.filter(e -> e.getInventoryManager().contains(inventoryManager));
        }
        model.addAttribute("inventories", inventoryStream.toList());
        return "inventoryManagement";
    }

    @PostMapping("/list")
    public String getByIndex(@RequestParam("materialName") String materialName, @RequestParam("inventoryName") String inventoryName,
                             @RequestParam("supplier") String supplier, @RequestParam("start") String start, @RequestParam("end") String end, HttpSession session, Model model) {
        List<EntryExitRecords> entryExitRecordsList = entryExitRecordsService.getAllEntryExitRecords();
        Stream<EntryExitRecords> tmp = entryExitRecordsList.stream();
        if (!materialName.isEmpty()) {
            tmp = tmp.filter(e -> e.getMaterialName().contains(materialName));
        }
        if (!inventoryName.isEmpty()) {
            tmp = tmp.filter(e -> e.getInventoryName().contains(inventoryName));
        }
        if (!supplier.isEmpty()) {
            tmp = tmp.filter(e -> e.getSupplierName().contains(supplier));
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (!start.isEmpty()) {
            tmp = tmp.filter(e -> {
                try {
                    return e.getRecordDate().after(sdf.parse(start));
                } catch (ParseException ex) {
                    throw new RuntimeException(ex);
                }
            });
        }
        if (!end.isEmpty()) {
            tmp = tmp.filter(e -> {
                try {
                    return e.getRecordDate().before(sdf.parse(end));
                } catch (ParseException ex) {
                    throw new RuntimeException(ex);
                }
            });
        }
        model.addAttribute("records", tmp.toList());
        return "inventoryKeeper";
    }

    @PostMapping("/totalMaterial")
    public String getTotalMaterial(@RequestParam("materialName") String materialName, HttpSession session, Model model) {
        List<TotalMaterial> totalMaterialList = totalMaterialService.getAllTotalMaterial();
        Stream<TotalMaterial> tmp = totalMaterialList.stream();
        if (!materialName.isEmpty()) {
            tmp = tmp.filter(e -> e.getMaterialName().contains(materialName));
        }
        model.addAttribute("totalMaterials", tmp.toList());
        return "warning";
    }

    @PostMapping("/updateMinimumStock")
    public String updateMinimumStock(@RequestParam("updateMaterialName") String updateMaterialName, @RequestParam("minimumStock") long minimumStock) {
        TotalMaterial totalMaterial = new TotalMaterial();
        totalMaterial.setMaterialName(updateMaterialName);
        totalMaterial.setMinimumStock(minimumStock);
        totalMaterialService.updateMinimumStockByMaterialName(totalMaterial);
        return "warning";
    }

    @PostMapping("/getRecord")
    public String getRecord(@RequestParam("materialName") String materialName, @RequestParam("recordStatus") String recordStatus, @RequestParam("materialNumber") long materialNumber,
                            @RequestParam("supplierName") String supplierName, @RequestParam("inventoryName") String inventoryName, HttpSession session, Model model) {
        if (recordStatus.equals("入库")) {
            try {
                TotalMaterial tmp = totalMaterialService.getTotalMaterialByName(materialName);
                entryExitRecordsService.addRecord(materialName, materialNumber, recordStatus, supplierName, inventoryName);
                long num = tmp.getMaterialTotalNumber() + materialNumber;
                tmp.setMaterialTotalNumber(num);
                totalMaterialService.updateMaterialTotalNumberByMaterialName(tmp);
            } catch (Exception e) {
                TotalMaterial newTotalMaterial = new TotalMaterial();
                newTotalMaterial.setMaterialName(materialName);
                newTotalMaterial.setMaterialTotalNumber(materialNumber);
                newTotalMaterial.setMinimumStock(0);
                newTotalMaterial.setWarningState(false);
                totalMaterialService.addTotalMaterial(newTotalMaterial);
            }

        } else if (recordStatus.equals("出库")) {
            if (totalMaterialService.getTotalMaterialByName(materialName) == null) {
                model.addAttribute("fail", "材料不存在");
                return "record";
            }
            if (totalMaterialService.getTotalMaterialByName(materialName).getMaterialTotalNumber() < materialNumber) {
                model.addAttribute("fail", "库存不足");
                return "record";
            }
            entryExitRecordsService.addRecord(materialName, materialNumber, recordStatus, supplierName, inventoryName);
            TotalMaterial totalMaterial = totalMaterialService.getTotalMaterialByName(materialName);
            long num = totalMaterial.getMaterialTotalNumber() - materialNumber;
            TotalMaterial tmp = new TotalMaterial();
            tmp.setMaterialName(materialName);
            tmp.setMaterialTotalNumber(num);
            tmp.setWarningState(num < totalMaterial.getMinimumStock());
            totalMaterialService.updateMaterialTotalNumberByMaterialName(tmp);
        }
        return "record";
    }

    @PostMapping("/supplier")
    public String getSupplierByIndex(@RequestParam("supplierName") String supplierName, Model model) {
        List<Map<String, Object>> list = orderService.supplierManagement();
        Stream<Map<String, Object>> tmp = list.stream();
        if (!supplierName.isEmpty()) {
            tmp = tmp.filter(l -> l.get("supplier_name").toString().contains(supplierName));
        }

        model.addAttribute("supplierQuery", tmp.toList());
        return "supplierManagement";
    }

    @PostMapping("/createSupplier")
    public String createSupplier(@RequestParam("newSupplierName") String newSupplierName, @RequestParam("newSupplierAddress") String newSupplierAddress,
                                 @RequestParam("newSupplierContact") String newSupplierContact, HttpSession session, Model model) {
        
        Supplier supplier = supplierService.getSupplierBySupplierName(newSupplierName);
        if(supplier!=null){
            model.addAttribute("createError", "该供应商已存在");
        }else {
            supplier = new Supplier();
            supplier.setSupplierName(newSupplierName);
            supplier.setPlace(newSupplierAddress);
            supplier.setPhone(newSupplierContact);
            supplierService.addSupplier(supplier);
        }
        List<Supplier> suppliers = supplierService.getAllSuppliers();
        session.setAttribute("suppliers", suppliers);
        return "supplierManagement";
    }
}
